package com.wgworkshop.pems.service;

import com.wgworkshop.pems.common.BusinessException;
import com.wgworkshop.pems.common.CommonUtils;
import com.wgworkshop.pems.entity.AttendanceEntity;
import com.wgworkshop.pems.entity.HolidayEntity;
import com.wgworkshop.pems.entity.StudentEntity;
import com.wgworkshop.pems.model.*;
import com.wgworkshop.pems.repository.AttendanceRepository;
import com.wgworkshop.pems.repository.ClassHourRepository;
import com.wgworkshop.pems.repository.HolidayRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 考勤服务接口实现类。
 * Created by wlc on 2017/7/9.
 */
@Service
public class AttendanceServiceImpl implements AttendanceService {
    @Autowired
    private AttendanceRepository attendanceRepository;
    @Autowired
    private ClassHourRepository classHourRepository;
    @Autowired
    private HolidayRepository holidayRepository;
    @Autowired
    private StudentService studentService;

    @Override
    public AttendanceModel save(AttendanceModel attendanceModel) {
        Long studentId = attendanceModel.getStudentId();
        studentService.checkExists(studentId);

        AttendanceEntity attendanceEntity = new AttendanceEntity();
        BeanUtils.copyProperties(attendanceModel, attendanceEntity);

        StudentEntity studentEntity = studentService.getRepository().findOne(studentId);
        attendanceEntity.setStudent(studentEntity);

        AttendanceEntity resultEntity = attendanceRepository.save(attendanceEntity);
        AttendanceModel resultModel = new AttendanceModel();
        BeanUtils.copyProperties(resultEntity, resultModel);
        resultModel.setStudentId(resultEntity.getStudent().getId());

        return resultModel;
    }

    @Override
    public void delete(Long id) {
        checkExists(id);
        attendanceRepository.delete(id);
    }

    @Override
    public AttendanceModel update(Long id, AttendanceModel attendanceModel) {
        checkExists(id);

        Long studentId = attendanceModel.getStudentId();
        StudentEntity studentEntity = null;
        if (studentId != null) {
            studentService.checkExists(studentId);
            studentEntity = studentService.getRepository().findOne(studentId);
        }

        AttendanceEntity attendanceEntity = attendanceRepository.findOne(id);
        String[] nullProperties = CommonUtils.getNullPropertyNames(attendanceModel);
        BeanUtils.copyProperties(attendanceModel, attendanceEntity, nullProperties);
        if (studentEntity != null) {
            attendanceEntity.setStudent(studentEntity);
        }

        AttendanceEntity resultEntity = attendanceRepository.save(attendanceEntity);
        AttendanceModel resultModel = new AttendanceModel();
        BeanUtils.copyProperties(resultEntity, resultModel);
        resultModel.setStudentId(resultEntity.getStudent().getId());

        return resultModel;
    }

    @Override
    public AttendanceModel update(AttendanceModel attendanceModel) {
        Long attendanceId = attendanceModel.getId();
        checkExists(attendanceId);

        Long studentId = attendanceModel.getStudentId();
        studentService.checkExists(studentId);

        StudentEntity studentEntity = studentService.getRepository().findOne(studentId);
        AttendanceEntity attendanceEntity = attendanceRepository.findOne(attendanceId);
        BeanUtils.copyProperties(attendanceModel, attendanceEntity);
        attendanceEntity.setStudent(studentEntity);

        AttendanceEntity resultEntity = attendanceRepository.save(attendanceEntity);
        AttendanceModel resultModel = new AttendanceModel();
        BeanUtils.copyProperties(resultEntity, resultModel);
        resultModel.setStudentId(resultEntity.getStudent().getId());

        return resultModel;
    }

    @Override
    public AttendanceModel findOne(Long id) {
        AttendanceEntity attendanceEntity = attendanceRepository.findOne(id);
        AttendanceModel attendanceModel = null;
        if (attendanceEntity != null) {
            attendanceModel = new AttendanceModel();
            BeanUtils.copyProperties(attendanceEntity, attendanceModel);
            attendanceModel.setStudentId(attendanceEntity.getStudent().getId());
        }
        return attendanceModel;
    }

    @Override
    public boolean exists(Long id) {
        return attendanceRepository.exists(id);
    }

    @Override
    public void checkExists(Long id) {
        if (!exists(id)) {
            throw new BusinessException(String.format("指定的考勤ID不存在[%s]。", id));
        }
    }

    @Override
    public AttendanceView getAttendanceView(int week, int classNum, int shift) {
        if (week < 0 || week > 6) {
            throw new BusinessException("指定的星期应该在0-6之间。");
        }

        CommonUtils.DateBoundary boundary = CommonUtils.calculateBoundaryDate(week, shift, 11, 1);

        List<Long> studentIds = new ArrayList<>();
        Iterable<ClassHourViewRecord> classHourRecords = classHourRepository.getAttendanceClassHourInfo(week, classNum);
        for (ClassHourViewRecord classHourRecord : classHourRecords) {
            studentIds.add(classHourRecord.getId());
        }

//        List<ClassHourViewRecord> classHourInfo = new ArrayList<>();
//        classHourRecords.forEach(classHourInfo::add);

        Iterable<AttendanceEntity> attendanceEntities = attendanceRepository.findByCourseDateBetweenAndStudentIdIn(boundary.start, boundary.end, studentIds);
        List<AttendanceModel> attendanceInfo = new ArrayList<>();
        for (AttendanceEntity attendanceEntity : attendanceEntities) {
            AttendanceModel attendanceModel = new AttendanceModel();
            BeanUtils.copyProperties(attendanceEntity, attendanceModel);
            attendanceModel.setStudentId(attendanceEntity.getStudent().getId());
            attendanceInfo.add(attendanceModel);
        }

        Iterable<HolidayEntity> holidayEntities = holidayRepository.findByHolidayBetween(boundary.start, boundary.end);
        List<HolidayModel> holidayInfo = CommonUtils.convertIterableToList(holidayEntities, HolidayModel.class);

        List<AttendanceViewRecord> viewRecords = new ArrayList<>();
        for (ClassHourViewRecord classHourRecord : classHourRecords) {
            AttendanceViewRecord viewRecord = new AttendanceViewRecord();
            viewRecord.setClassHourInfo(classHourRecord);

            List<AttendanceModel> attendanceList = new ArrayList<>();
            for (AttendanceModel attendance : attendanceInfo) {
                if (classHourRecord.getId().compareTo(attendance.getStudentId()) == 0) {
                    attendanceList.add(attendance);
                }
            }
            viewRecord.setAttendanceInfo(attendanceList);

            viewRecords.add(viewRecord);
        }

        AttendanceView view = new AttendanceView();
        view.setAttendanceList(viewRecords);
        view.setHolidayInfo(holidayInfo);

        return view;
    }

    @Override
    public AttendanceRepository getRepository() {
        return attendanceRepository;
    }
}
